package cn.wolfcode.service.impl;

import cn.wolfcode.common.domain.UserInfo;
import cn.wolfcode.common.exception.BusinessException;
import cn.wolfcode.common.web.Result;
import cn.wolfcode.domain.OrderInfo;
import cn.wolfcode.domain.Product;
import cn.wolfcode.domain.SeckillProduct;
import cn.wolfcode.domain.SeckillProductVo;
import cn.wolfcode.feign.ProductFeignApi;
import cn.wolfcode.mapper.SeckillProductMapper;
import cn.wolfcode.redis.SeckillRedisKey;
import cn.wolfcode.service.ISeckillProductService;
import cn.wolfcode.util.IdGenerateUtil;
import cn.wolfcode.util.UserUtil;
import cn.wolfcode.web.msg.SeckillCodeMsg;
import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @author LuoRis
 */
@Service
public class SeckillProductServiceImpl implements ISeckillProductService {
    @Autowired
    private SeckillProductMapper seckillProductMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private ProductFeignApi productFeignApi;
    @Autowired
    private OrderInfoSeviceImpl orderInfoSevice;

    @Override
    public Result<List<SeckillProductVo>> queryCurrentlySeckillProduct(Integer time) {
        List<SeckillProduct> seckillProducts = seckillProductMapper.queryCurrentlySeckillProduct(time);
        List<Long> ids = new ArrayList<>();
        List<SeckillProductVo> seckillProductVos = new ArrayList<>();


        for (SeckillProduct seckillProduct : seckillProducts) {
            SeckillProductVo vo = new SeckillProductVo();
            ids.add(seckillProduct.getProductId());
            BeanUtils.copyProperties(seckillProduct,vo);
            seckillProductVos.add(vo);
        }

        Result<List<Product>> products = productFeignApi.queryProductByIds(ids);

        /**
         * 如果远程调用失败,抛出执行自定义异常
         */
        if (products==null||products.hasError()){
            throw new BusinessException(SeckillCodeMsg.SECKILL_PRODUCT_SERVER_ERROR);
        }

        List<Product> data = products.getData();

        if (data!=null&&data.size()>0){
            for (Product product : data) {
                for (SeckillProductVo seckillProductVo : seckillProductVos) {
                    if (seckillProductVo.getProductId().equals(product.getId())){
                        Long seckillId = seckillProductVo.getId();
                        BeanUtils.copyProperties(product,seckillProductVo);
                        seckillProductVo.setId(seckillId);
                    }
                }
            }
        }

        return Result.success(seckillProductVos);
    }

    @Override
    public List<SeckillProductVo> queryByTime(int time) {
        List<Object> list = redisTemplate.opsForHash().values(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""));
        List<SeckillProductVo> vos = new ArrayList<>();
        for (Object o : list) {
            SeckillProductVo seckillProductVo = JSON.parseObject(o+"", SeckillProductVo.class);
            vos.add(seckillProductVo);
        }
        return vos;
    }

    @Override
    public SeckillProductVo find(String seckillId, int time) {
        Object value = redisTemplate.opsForHash().get(SeckillRedisKey.SECKILL_PRODUCT_LIST.getRealKey(time + ""), seckillId);
        SeckillProductVo seckillProductVo = JSON.parseObject(value + "", SeckillProductVo.class);
        return seckillProductVo;
    }

    @Override
    public OrderInfo doSeckill(int time, Long seckillId, Long phone) {
        //减少真实库存
        seckillProductMapper.decrStock(seckillId);
        //创建订单
        OrderInfo orderInfo = orderInfoSevice.createOrder(time,seckillId,phone);
        //往redis存一个数据 seckill_order_set:用户手机号:商品id (用于判断用户是否重复下单)
        //redisTemplate.opsForSet().add(SeckillRedisKey.SECKILL_ORDER_SET.getRealKey(time+""),phone + ":" + seckillId);
        return orderInfo;
    }



    @Override
    public int getStockCount(Long seckillId) {
        return seckillProductMapper.getStockCount(seckillId);
    }

    @Override
    public int selectProductCount(Long seckillId) {
        return seckillProductMapper.getStockCount(seckillId);
    }

    @Override
    public void incrCount(Long seckillId) {
        seckillProductMapper.incrStock(seckillId);
    }
}